package com.wzc.user.service.impl;

import com.wzc.basic.constant.RegisterConstant;
import com.wzc.basic.exception.BusinessException;
import com.wzc.basic.service.impl.BaseServiceImpl;
import com.wzc.basic.util.Md5Utils;
import com.wzc.basic.util.StrUtils;
import com.wzc.user.domain.Logininfo;
import com.wzc.user.domain.User;
import com.wzc.user.dto.RegisterDto;
import com.wzc.user.mapper.LogininfoMapper;
import com.wzc.user.mapper.UserMapper;
import com.wzc.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Override
    public void phoneRegister(RegisterDto dto) {
        // 获取前端传回的四个参数
        String phone = dto.getPhone(); // 手机号码
        String verifyCode = dto.getVerifyCode(); // 验证码
        String password = dto.getPassword(); // 密码
        String confirmPassword = dto.getConfirmPassword(); // 二次确认密码

        // 1. 校验，四个参数非空校验
        if(StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(verifyCode)
                || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(confirmPassword)){
           throw new BusinessException("参数不能为空，请认真填写！");
        }

        // 2. 校验两次密码是否一致
        if(!password.equals(confirmPassword)){
            throw new BusinessException("密码不一致，请重新输入！");
        }

        // 3. 校验手机号码是否被注册过
        User byPhone = userMapper.findByPhone(phone);
        if (byPhone != null) {
            throw new BusinessException("改号码已经被注册，请输入密码登录！");
        }

        // 4. 校验验证码是过期
        Object obj = redisTemplate.opsForValue().get(phone + RegisterConstant.PHONEREGISTER);
        if(obj == null){ // 为空  已过期
            throw new BusinessException("验证码已过期，请重新获取！");
        }
        // 5. 验证码没过期则校验验证码是否正确
        String redisCode = obj.toString().split(":")[0]; // 获取验证码
        if(!verifyCode.equals(redisCode)){ // 验证码错误
            throw new BusinessException("验证码错误，请重新输入！");
        }

        // 以上校验都同过则成功注册，将数据保存到相应的表（先保存logininfo表）
        // 先去获取logininfo对象和user对象

        // 先调用方法dto2Logininfo 获取Logininfo对象
        Logininfo logininfo = dto2Logininfo(dto);

        // 再通过logininfo对象获取user对象
        User user = logininfo2User(logininfo);

        // 先保存logininfo表，返回自增的主键
        logininfoMapper.save(logininfo);

        // 把自增的主键赋值给user对象， 再保存user。
        user.setLogininfo_id(logininfo.getId());
        userMapper.save(user);

    }

    /**
     * 该方式主要用来创建logininfo对象
     * 参数：RegisterDto dto 前端页面传来的四个参数
     * @param dto
     * @return
     */
    public Logininfo dto2Logininfo(RegisterDto dto) {
        Logininfo logininfo = new Logininfo();

        // 将前端页面数据赋值(添加数据)给相应字段，再保存
        logininfo.setUsername(dto.getPhone()); // 用户名
        logininfo.setPhone(dto.getPhone()); // 电话
        logininfo.setType(1); // 0：管理员   1：用户
        String salt = StrUtils.getComplexRandomString(32); // 调用方法生成盐值
        // 通过盐值和密码进行加密   加盐加密：
        String dbPassword = Md5Utils.encrypByMd5(salt + dto.getPassword());
        logininfo.setSalt(salt); // 盐值
        logininfo.setPassword(dbPassword); // 加密后的密码

        return logininfo;
    }


    /**
     *
     * @param logininfo
     * @return
     */
    private User logininfo2User(Logininfo logininfo) {
        User user = new User();
        // 通过logininfo 相同的属性的数据复制到user
        BeanUtils.copyProperties(logininfo,user);
        return  user;
    }














}
